<?php 
/** create by fu */
namespace app\api\service;

use \think\Exception;
use app\lib\exception\weChatException;
use app\api\model\User as UserModel;
use app\api\service\Token;
use app\lib\enum\ScopeEnum;
/**
 * 
 */
class UserToken extends Token
{
	
	protected $code;
	protected $wxAppID;
	protected $wxAppSecret;
	protected $wxLoginUrl;
    
    // 拼接url
	function __construct($code)
	{
		$this->code = $code;
		$this->wxAppID = config('wx.app_id');
		$this->wxAppSecret = config('wx.app_secret');
		$this->wxLoginUrl = sprintf(config('wx.login_url'),$this->wxAppID,$this->wxAppSecret,$this->code);
		 
	}

	// 带着code 去获取session_key及openID
	public function get()
	{
		// 请求微信 https地址 
		$result = curl_get($this->wxLoginUrl);//p($result);
		//将字符串变为数组   第二参数为true  否则为对象
		$wxResult = json_decode($result,true);

		if(empty($wxResult))
		{
			throw new Exception("获取session_key及openID异常，内部错误");
		}
		else
		{
			//返回errCode 说明调用失败
			if(array_key_exists('errcode', $wxResult)){
				$this->processLoginError($wxResult);
            
            //创建 token 并存入缓存
			}else{
				return $this->grantToken($wxResult);
                
			}
		}

	}
	/** 1 拿到openid
	 *  2 查数据库是否存在这个openid
	 *  3 存在不处理，否则新增一条带openid的user记录
	 *  4 生成令牌，准备缓存数据 并写入
	 *  5 返回令牌
	 */
	private function grantToken($wxResult)
	{
		
		$users = UserModel::getByOpenID($wxResult['openid']);
		if($users){
			$uid = $users->id;
		}else{
			$uid = $this->newUser($wxResult);
		}
		
		// 准备缓存数据
		$cachedValue = $this->prepareCachedValue($wxResult,$uid);

		// 生成令牌 并存入缓存
		$token = $this->saveToCache($cachedValue);
		return $token;

	}
	//创建令牌并存入缓存 缓存失效=令牌失效
	private function saveToCache($cachedValue)
	{
		$key = self::generateToken();
		//转成字符串
		$value = json_encode($cachedValue);
		$expire_in = config('setting.token_expire_in');

		$request = cache($key,$value,$expire_in);
		if(!$request){
			throw new TokenException(['msg'=>'服务器缓存异常','errorCode'=>10005]);
		}
		return $key;
	}
	//拼接 缓存数据
	private function prepareCachedValue($wxResult,$uid)
	{
		$cachedValue = $wxResult;
		$cachedValue['uid'] = $uid;
		// 16 代表app用户的权限值
		$cachedValue['scope'] = ScopeEnum::User;

		return $cachedValue;
	}

	private function newUser($wxResult)
	{
		$user = UserModel::create([
				'openid'=>$wxResult['openid'],
			]);
		return $user->id;
	}

	//抛出错误
	private function processLoginError($wxResult)
	{
		throw new weChatException([
			'msg' => $wxResult['errmsg'],
			'errorCode' => $wxResult['errcode'],

		]);
		
	}

}



 ?>